using NUnit.Framework;

namespace ValidationFramework.Tests
{

    enum Value
    {
        good,
        bad
    }
    [TestFixture]
    public class RequiredEnumRuleAttributeTest
    {
        [Test]
        public void CheckDefaultValuesNotNullable()
        {
            var ruleAttribute = new RequiredEnumRuleAttribute();
            Assert.IsNull(ruleAttribute.ErrorMessage);
            Assert.IsNull(ruleAttribute.InitialValueAsString);
            Assert.IsNull(ruleAttribute.InitialValueAsLong);

            var propertyRule = (RequiredRule<Value>)ruleAttribute.CreateRule(new MockPropertyDescriptor<Value>("foo"));
            var parameterRule = (RequiredRule<Value>)ruleAttribute.CreateRule(new MockParameterDescriptor<Value>("foo"));

            Assert.IsNull(propertyRule.ErrorMessage);
            Assert.AreEqual(Value.good, propertyRule.InitialValue);

            Assert.IsNull(parameterRule.ErrorMessage);
            Assert.AreEqual(Value.good, parameterRule.InitialValue);

        }

        [Test]
        public void CheckDefaultValuesNullable()
        {
            var ruleAttribute = new RequiredEnumRuleAttribute();
            Assert.IsNull(ruleAttribute.InitialValueAsString);
            Assert.IsNull(ruleAttribute.InitialValueAsLong);

            var propertyRule = (RequiredRule<Value>)ruleAttribute.CreateRule(new MockPropertyDescriptor<Value?>("foo"));
            var parameterRule = (RequiredRule<Value>)ruleAttribute.CreateRule(new MockParameterDescriptor<Value?>("foo"));

            Assert.IsFalse(propertyRule.HasInitialValue);
            Assert.IsFalse(parameterRule.HasInitialValue);
        }

        [Test]
        public void CheckNonDefaultValuesWithString()
        {
            const string expectedInitialValueString = "bad";
            var ruleAttribute = new RequiredEnumRuleAttribute(expectedInitialValueString);
            Assert.AreEqual(expectedInitialValueString, ruleAttribute.InitialValueAsString);
            Assert.IsNull(ruleAttribute.InitialValueAsLong);

            var propertyRule = (RequiredRule<Value>)ruleAttribute.CreateRule(new MockPropertyDescriptor<Value>("foo"));
            var parameterRule = (RequiredRule<Value>)ruleAttribute.CreateRule(new MockParameterDescriptor<Value>("foo"));

            Assert.AreEqual(Value.bad, propertyRule.InitialValue);
            Assert.IsTrue(propertyRule.HasInitialValue);

            Assert.AreEqual(Value.bad, parameterRule.InitialValue);
            Assert.IsTrue(parameterRule.HasInitialValue);

        }
        [Test]
        public void CheckNonDefaultValuesWIthLong()
        {
            var ruleAttribute = new RequiredEnumRuleAttribute((long)Value.bad);
            Assert.IsNull(ruleAttribute.InitialValueAsString);
            Assert.AreEqual((long)Value.bad, ruleAttribute.InitialValueAsLong);

            var propertyRule = (RequiredRule<Value>)ruleAttribute.CreateRule(new MockPropertyDescriptor<Value>("foo"));
            var parameterRule = (RequiredRule<Value>)ruleAttribute.CreateRule(new MockParameterDescriptor<Value>("foo"));

            Assert.AreEqual(Value.bad, propertyRule.InitialValue);
            Assert.IsTrue(propertyRule.HasInitialValue);

            Assert.AreEqual(Value.bad, parameterRule.InitialValue);
            Assert.IsTrue(parameterRule.HasInitialValue);

        }


        [Test]
        public void CallAttributeTester()
        {
            AttributeTester.CheckDefaultValues<Value>(new RequiredEnumRuleAttribute(), true, true);
            AttributeTester.CheckNonDefaultValues<Value>(new RequiredEnumRuleAttribute(), true, true);
            AttributeTester.CheckDefaultValues<Value>(new RequiredEnumRuleAttribute("bad"), true, true);
            AttributeTester.CheckNonDefaultValues<Value>(new RequiredEnumRuleAttribute("bad"), true, true);
            AttributeTester.CheckDefaultValues<Value>(new RequiredEnumRuleAttribute((long)Value.bad), true, true);
            AttributeTester.CheckNonDefaultValues<Value>(new RequiredEnumRuleAttribute((long)Value.bad), true, true);
        }
    }
}